home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / djgpp / diffs / gdb-4.12 / gdb / go32targ.c < prev    next >
Encoding:
Text File  |  1994-08-05  |  13.3 KB  |  490 lines

  1. *** orig/gdb-4.12/gdb/go32targ.c    Tue Jul 26 01:10:40 1994
  2. --- src/gdb-4.12/gdb/go32targ.c    Wed Jul 27 02:03:38 1994
  3. ***************
  4. *** 0 ****
  5. --- 1,484 ----
  6. + /* Target-vector operations for controlling go32 processes, for GDB.
  7. +    Copyright 1994 Free Software Foundation, Inc.
  8. +    Contributed by DJ Delorie.
  9. + This file is part of GDB.
  10. + This program is free software; you can redistribute it and/or modify
  11. + it under the terms of the GNU General Public License as published by
  12. + the Free Software Foundation; either version 2 of the License, or
  13. + (at your option) any later version.
  14. + This program is distributed in the hope that it will be useful,
  15. + but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17. + GNU General Public License for more details.
  18. + You should have received a copy of the GNU General Public License
  19. + along with this program; if not, write to the Free Software
  20. + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  21. + #include "defs.h"
  22. + #include "frame.h"  /* required by inferior.h */
  23. + #include "inferior.h"
  24. + #include "target.h"
  25. + #include "wait.h"
  26. + #include "gdbcore.h"
  27. + #include "command.h"
  28. + #include <signal.h>
  29. + extern char **environ;
  30. + /* Forward declaration */
  31. + extern struct target_ops go32_ops;
  32. + /* ╔════════════════════════════════════════════════════════════════════════════╗
  33. +    ║  Go32's external debugger interface routines                ║
  34. +    ╚════════════════════════════════════════════════════════════════════════════╝ */
  35. + #define SOME_PID 42
  36. + int prog_has_started = 0;
  37. + #include <sys/farptr.h>
  38. + #define far
  39. + #include <../go32/gotypes.h>    /* from go32 sources */
  40. + #include <../go32/tss.h>
  41. + #include <../go32/extdebug.h>
  42. + #include <../go32/paging.h>
  43. + static ExternalDebuggerInfo edi;
  44. + static TSS a_tss;
  45. + static AREAS areas[MAX_AREA];
  46. + static int my_ds;
  47. + static int app_ds;
  48. + static int edi_seg;
  49. + static int edi_ofs;
  50. + #define r_ofs(x) ((int)(&(((TSS *)0)->x)))
  51. + static struct {
  52. +   int tss_ofs;
  53. +   int size;
  54. + } regno_mapping[] = {
  55. +   r_ofs(tss_eax), 4,
  56. +   r_ofs(tss_ecx), 4,
  57. +   r_ofs(tss_edx), 4,
  58. +   r_ofs(tss_ebx), 4,
  59. +   r_ofs(tss_esp), 4,
  60. +   r_ofs(tss_ebp), 4,
  61. +   r_ofs(tss_esi), 4,
  62. +   r_ofs(tss_edi), 4,
  63. +   r_ofs(tss_eip), 4,
  64. +   r_ofs(tss_eflags), 4,
  65. +   r_ofs(tss_cs), 2,
  66. +   r_ofs(tss_ss), 2,
  67. +   r_ofs(tss_ds), 2,
  68. +   r_ofs(tss_es), 2,
  69. +   r_ofs(tss_fs), 2,
  70. +   r_ofs(tss_gs), 2
  71. + };
  72. + static struct {
  73. +   int go32_sig;
  74. +   int gdb_sig;
  75. + } sig_map[] = {
  76. +   0, TARGET_SIGNAL_BUS,
  77. +   1, TARGET_SIGNAL_TRAP,
  78. +   2, TARGET_SIGNAL_UNKNOWN,
  79. +   3, TARGET_SIGNAL_TRAP,
  80. +   4, TARGET_SIGNAL_FPE,
  81. +   5, TARGET_SIGNAL_SEGV,
  82. +   6, TARGET_SIGNAL_ILL,
  83. +   7, TARGET_SIGNAL_FPE,
  84. +   8, TARGET_SIGNAL_BUS,
  85. +   9, TARGET_SIGNAL_FPE,
  86. +   10, TARGET_SIGNAL_BUS,
  87. +   11, TARGET_SIGNAL_SEGV,
  88. +   12, TARGET_SIGNAL_SEGV,
  89. +   13, TARGET_SIGNAL_SEGV,
  90. +   14, TARGET_SIGNAL_SEGV,
  91. +   16, TARGET_SIGNAL_FPE,
  92. +   31, TARGET_SIGNAL_ILL,
  93. +   -1,-1
  94. + };
  95. + static void go32_edi_init()
  96. + {
  97. +   int i;
  98. +   asm("movw $0xfe01,%ax");
  99. +   asm("int $0x21");
  100. +   asm("movl %edx,_edi_seg");
  101. +   asm("movl %eax,_edi_ofs");
  102. +   asm("xor  %eax,%eax");
  103. +   asm("movw %ds,%ax");
  104. +   asm("movl %eax,_my_ds");
  105. +   movedata(edi_seg, edi_ofs, my_ds, (int)(&edi), sizeof(edi));
  106. +   movedata(edi.a_tss_seg, edi.a_tss_ofs, my_ds, (int)(&a_tss), sizeof(TSS));
  107. +   app_ds = a_tss.tss_ds;
  108. +   movedata(edi.areas_seg, edi.areas_ofs, my_ds, (int)areas, sizeof(areas));
  109. +   for (i=0; i<MAX_AREA; i++)
  110. +   {
  111. +     areas[i].first_addr -= edi.app_base;
  112. +     areas[i].last_addr -= edi.app_base;
  113. +   }
  114. + }
  115. + static void go32_edi_run_child(void)
  116. + {
  117. +   int i;
  118. +   prog_has_started = 1;
  119. +   movedata(my_ds, (int)(&edi), edi_seg, edi_ofs, sizeof(edi));
  120. +   movedata(my_ds, (int)(&a_tss), edi.a_tss_seg, edi.a_tss_ofs, sizeof(TSS));
  121. +   asm("movw $0xfe00,%ax");
  122. +   asm("int $0x21");
  123. +   movedata(edi_seg, edi_ofs, my_ds, (int)(&edi), sizeof(edi));
  124. +   movedata(edi.a_tss_seg, edi.a_tss_ofs, my_ds, (int)(&a_tss), sizeof(TSS));
  125. +   movedata(edi.areas_seg, edi.areas_ofs, my_ds, (int)areas, sizeof(areas));
  126. +   for (i=0; i<MAX_AREA; i++)
  127. +   {
  128. +     areas[i].first_addr -= edi.app_base;
  129. +     areas[i].last_addr -= edi.app_base;
  130. +   }
  131. + }
  132. + static int invalid_addr(word32 a, unsigned len)
  133. + {
  134. +   int i;
  135. +   if ((int)invalid_addr > 0)
  136. +     return 0;
  137. +   for (i=0; i<MAX_AREA; i++)
  138. +     if (a>=areas[i].first_addr && (a+len-1) <= areas[i].last_addr)
  139. +       return 0;
  140. +   return 1;
  141. + }
  142. + static int go32_edi_read_child(word32 child_addr, void *buf, unsigned len)
  143. + {
  144. +   if (invalid_addr(child_addr, len))
  145. +     return 0;
  146. +   movedata(app_ds, child_addr, my_ds, (int)buf, len);
  147. +   return 0;
  148. + }
  149. + static int go32_edi_write_child(word32 child_addr, void *buf, unsigned len)
  150. + {
  151. +   if (invalid_addr(child_addr, len))
  152. +     return 0;
  153. +   movedata(my_ds, (int)buf, app_ds, child_addr, len);
  154. +   return 0;
  155. + }
  156. + static char *new_argv[3] = {
  157. +   "gdb",
  158. +   0,
  159. +   0
  160. + };
  161. + void
  162. + init_go32_extdebug(int *argc, char ***argv)
  163. + {
  164. +   char *fn;
  165. +   int i, v;
  166. +   int tenvp;
  167. +   go32_edi_init();
  168. +   fn = (char *)malloc(edi.filename_len + 1);
  169. +   movedata(edi.filename_seg, edi.filename_ofs, my_ds, (int)(fn), edi.filename_len+1);
  170. + #if 0
  171. +   printf("filename: %s\n", fn);
  172. +   printf("text: %#08x - %#08x\n", areas[A_text].first_addr, areas[A_text].last_addr);
  173. +   printf("data: %#08x - %#08x\n", areas[A_data].first_addr, areas[A_data].last_addr);
  174. +   printf("bss:  %#08x - %#08x\n", areas[A_bss].first_addr, areas[A_bss].last_addr);
  175. +   printf("stack: %#x\n", a_tss.tss_esp);
  176. + #endif
  177. +   go32_edi_read_child(a_tss.tss_esp+8, &tenvp, 4);
  178. +   
  179. +   new_argv[1] = fn;
  180. +   
  181. +   for (i=0; ; i++)
  182. +   {
  183. +     int ep;
  184. +     char *s;
  185. +     go32_edi_read_child(tenvp+i*4, &ep, 4);
  186. +     if (!ep)
  187. +       break;
  188. +   }
  189. +   environ = (char **)malloc((i+1) * sizeof(char *));
  190. +   for (i=0; ; i++)
  191. +   {
  192. +     int ep;
  193. +     char *s;
  194. +     go32_edi_read_child(tenvp+i*4, &ep, 4);
  195. +     if (!ep)
  196. +     {
  197. +       environ[i] = 0;
  198. +       break;
  199. +     }
  200. +     _farsetsel(app_ds);
  201. +     for (v=0; _farnspeekb(ep+v); v++);
  202. +     environ[i] = (char *)malloc(v+1);
  203. +     go32_edi_read_child(ep, environ[i], v+1);
  204. +   }
  205. +   
  206. +   *argc = 2;
  207. +   *argv = new_argv;
  208. + }
  209. + /* ───────────────────────────────────────────────────────────────────────────── */
  210. + /* special sbrk that uses local heap and zeros memory. */
  211. + void *
  212. + sbrk(int l)
  213. + {
  214. +   extern int end;
  215. +   static int sold = (int)&end;
  216. +   memset(sold, 0, l);
  217. +   sold += l;
  218. +   return (void *)(sold-l);
  219. + }
  220. + /* ═════════════════════════════════════════════════════════════════════════════ */
  221. + static void
  222. + go32_open(char *name, int from_tty)
  223. + {
  224. +   printf("Use the `run' command to run go32 programs\n");
  225. + }
  226. + /* ───────────────────────────────────────────────────────────────────────────── */
  227. + static void go32_close(int quitting)
  228. + {
  229. + }
  230. + /* ───────────────────────────────────────────────────────────────────────────── */
  231. + static void
  232. + go32_attach(char *args, int from_tty)
  233. + {
  234. +   printf("Use the `run' command to run go32 programs\n");
  235. + }
  236. + /* ───────────────────────────────────────────────────────────────────────────── */
  237. + static void
  238. + go32_detach(char *args, int from_tty)
  239. + {
  240. + }
  241. + /* ───────────────────────────────────────────────────────────────────────────── */
  242. + static int resume_is_step;
  243. + static void
  244. + go32_resume(int pid, int step, enum target_signal siggnal)
  245. + {
  246. +   resume_is_step = step;
  247. + }
  248. + /* ───────────────────────────────────────────────────────────────────────────── */
  249. + static int
  250. + go32_wait(int pid, struct target_waitstatus *status)
  251. + {
  252. + /*  printf("go32_wait %d\n", pid); */
  253. +   if (resume_is_step)
  254. +     a_tss.tss_eflags |= 0x0100;
  255. +   else
  256. +     a_tss.tss_eflags &= 0xfeff;
  257. +   go32_edi_run_child();
  258. +   if (a_tss.tss_irqn == 0x21)
  259. +   {
  260. +     status->kind = TARGET_WAITKIND_EXITED;
  261. +     status->value.integer = a_tss.tss_eax & 0xff;
  262. +   }
  263. +   else
  264. +   {
  265. +     int i;
  266. +     status->value.sig = TARGET_SIGNAL_UNKNOWN;
  267. +     for (i=0; sig_map[i].go32_sig != -1; i++)
  268. +       if (a_tss.tss_irqn == sig_map[i].go32_sig)
  269. +       {
  270. +         status->value.sig = sig_map[i].gdb_sig;
  271. +         break;
  272. +       }
  273. +     status->kind = TARGET_WAITKIND_STOPPED;
  274. +   }
  275. +   return SOME_PID;
  276. + }
  277. + /* ───────────────────────────────────────────────────────────────────────────── */
  278. + static void
  279. + go32_fetch_registers(int regno)
  280. + {
  281. +   if (regno >= 0)
  282. +     supply_register(regno, (char *)&a_tss + regno_mapping[regno].tss_ofs);
  283. +   else
  284. +   {
  285. +     int r;
  286. +     for (r=0; r<sizeof(regno_mapping)/sizeof(regno_mapping[0]); r++)
  287. +       supply_register(r, (char *)&a_tss + regno_mapping[r].tss_ofs);
  288. +   }
  289. + }
  290. + /* ───────────────────────────────────────────────────────────────────────────── */
  291. + static void store_register(int regno)
  292. + {
  293. +   char *rp = (char *)&a_tss + regno_mapping[regno].tss_ofs;
  294. +   int v = *(int *)(®isters[REGISTER_BYTE(regno)]);
  295. +   switch (regno_mapping[regno].size)
  296. +   {
  297. +     case 4:
  298. +       *(int *)rp = v;
  299. +       break;
  300. +     case 2:
  301. +       *(short *)rp = v;
  302. +       break;
  303. +   }
  304. + }
  305. + static void
  306. + go32_store_registers(int regno)
  307. + {
  308. +   if (regno >= 0)
  309. +     store_register(regno);
  310. +   else
  311. +   {
  312. +     int r;
  313. +     for (r=0; r<sizeof(regno_mapping)/sizeof(regno_mapping[0]); r++)
  314. +       store_register(regno);
  315. +   }
  316. + }
  317. + /* ───────────────────────────────────────────────────────────────────────────── */
  318. + static void
  319. + go32_prepare_to_store(void)
  320. + {
  321. + }
  322. + /* ───────────────────────────────────────────────────────────────────────────── */
  323. + static int
  324. + go32_xfer_memory(CORE_ADDR memaddr, char *myaddr, int len, int write,
  325. +          struct target_ops *target)
  326. + {
  327. + /*  printf("go32_xfer_memory %x %x %d %d\n", memaddr, myaddr, len, write); */
  328. +   if (write)
  329. +     go32_edi_write_child(memaddr, myaddr, len);
  330. +   else
  331. +     go32_edi_read_child(memaddr, myaddr, len);
  332. +   return len;
  333. + }
  334. + /* ───────────────────────────────────────────────────────────────────────────── */
  335. + static void
  336. + go32_files_info(struct target_ops *target)
  337. + {
  338. +   printf_filtered("You are running a go32 program called `%s'\n", new_argv[1]);
  339. + }
  340. + /* ───────────────────────────────────────────────────────────────────────────── */
  341. + static void
  342. + go32_kill_inferior(void)
  343. + {
  344. +   /* nothing to do */
  345. + }
  346. + /* ───────────────────────────────────────────────────────────────────────────── */
  347. + static void
  348. + go32_create_inferior(char *exec_file, char *args, char **env)
  349. + {
  350. +   if (prog_has_started)
  351. +   {
  352. +     printf("The program has been started once already.  Please quit and restart gdb.\n");
  353. +     return;
  354. +   }
  355. +   inferior_pid = SOME_PID;
  356. +   push_target(&go32_ops);
  357. +   clear_proceed_status();
  358. +   proceed((CORE_ADDR) -1, TARGET_SIGNAL_0, 0);
  359. + }
  360. + /* ───────────────────────────────────────────────────────────────────────────── */
  361. + static void
  362. + go32_mourn_inferior(void)
  363. + {
  364. +   unpush_target(&go32_ops);
  365. + }
  366. + /* ───────────────────────────────────────────────────────────────────────────── */
  367. + static int go32_can_run(void)
  368. + {
  369. +   return 1;
  370. + }
  371. + /* ───────────────────────────────────────────────────────────────────────────── */
  372. + static void ignore(void) {}
  373. + static void ignore2(char *a,int b) {}
  374. + /* ═════════════════════════════════════════════════════════════════════════════ */
  375. + struct target_ops go32_ops = {
  376. +   "go32",            /* to_shortname */
  377. +   "go32 target process",    /* to_longname */
  378. +   "Program loaded by go32, when gdb is used as an external debugger",    /* to_doc */
  379. +   go32_open,            /* to_open */
  380. +   go32_close,            /* to_close */
  381. +   go32_attach,            /* to_attach */
  382. +   go32_detach,             /* to_detach */
  383. +   go32_resume,            /* to_resume */
  384. +   go32_wait,            /* to_wait */
  385. +   go32_fetch_registers,        /* to_fetch_registers */
  386. +   go32_store_registers,        /* to_store_registers */
  387. +   go32_prepare_to_store,    /* to_prepare_to_store */
  388. +   go32_xfer_memory,        /* to_xfer_memory */
  389. +   go32_files_info,        /* to_files_info */
  390. +   memory_insert_breakpoint,    /* to_insert_breakpoint */
  391. +   memory_remove_breakpoint,    /* to_remove_breakpoint */
  392. +   ignore,            /* to_terminal_init */
  393. +   ignore,             /* to_terminal_inferior */
  394. +   ignore,            /* to_terminal_ours_for_output */
  395. +   ignore,            /* to_terminal_ours */
  396. +   ignore2,            /* to_terminal_info */
  397. +   go32_kill_inferior,        /* to_kill */
  398. +   0,                /* to_load */
  399. +   0,                /* to_lookup_symbol */
  400. +   go32_create_inferior,        /* to_create_inferior */
  401. +   go32_mourn_inferior,        /* to_mourn_inferior */
  402. +   go32_can_run,            /* to_can_run */
  403. +   0,                 /* to_notice_signals */
  404. +   process_stratum,        /* to_stratum */
  405. +   0,                /* to_next */
  406. +   1,                /* to_has_all_memory */
  407. +   1,                /* to_has_memory */
  408. +   1,                /* to_has_stack */
  409. +   1,                /* to_has_registers */
  410. +   1,                /* to_has_execution */
  411. +   0,                /* sections */
  412. +   0,                /* sections_end */
  413. +   OPS_MAGIC            /* to_magic */
  414. + };
  415. + void
  416. + _initialize_inftarg ()
  417. + {
  418. +   add_target (&go32_ops);
  419. + }
  420.